在前面幾天我們一直強調 React 的專案是由許多 元件(Component) 所組合而成的,可以說這些元件就是 React 的一切,但是我們該重複利用我們所製作出來的元件呢?
有個很簡單的方法就是複製元件,像是下面的程式碼
這邊我先做出代辦事項的元件
// src/components/Items
const Item = () => {
return (
<div>
<div className="item">
<p>記事:今天要學習 React</p>
<p>紀錄時間:2022/9/20</p>
</div>
</div>
)
}
export { Item }
加上一些簡單的 CSS
/* src/styles/index.css */
.item {
width: 50%;
border: 1px solid #000;
margin-bottom: 20px;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
最後在 src/index.js
呈現
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Item } from './components/Item';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// 在這邊複製貼上
<Item />
<Item />
<Item />
//
</React.StrictMode>
);
簡單又暴力的複製貼上就可以使我們的元件重複利用,這也是在 React 的世界中,強調元件化的重要性
但是好像會出現一個大問題,如果我要客製化的的元件內容時該怎麼辦?
像是例子中,你所希望的代辦事項並不會每一條項目都是一樣,甚至時間也不會一樣,但是我們將代辦事項的內容寫死在我們的 Items.js
這個 Component 中,導致我們只能將他快速的重複複製貼上,卻不能客製化內容
這時救星出現了!!! Props
對於 Props React 的官方網站給出的定義是這樣
當 React 看到由使用者定義 component 的 element 時,它將 JSX 屬性 和 children 作為 single object 傳遞給該 component。我們稱這個 object 為「props」
是不是完全看不懂 什麼是 JSX 屬性?? Childred 是小孩這點我知道
這邊讓我來說白話文吧,並且簡單的舉例吧
在 HTML 中你可能會寫出這樣的 code 來區分兩個不同的 div,並對他們做不同的操作,像是不同的 div 加上 CSS 或是使用 JavaScript 對不同的 div 加上監聽器 addEventListener(),監聽不同的事件,來做出相對應的行為
<div class="divfirst">我是 1 號</div>
<div class="divsecond">我是 2 號</div>
Props 也是一樣的,Props 就是 properties(特性),目的也是要區分各個 Components 不同的特性,你也可以稱之為屬性
舉個簡單的例子,我們來自定義我們做好的元件
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Hello } from './components/Hello';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<>
這邊我們為每個元件加上一個 name 屬性,這就是 JSX 屬性
這個其實就是 React 中的 Props
<Hello name={"Zhan"} />
<Hello name={"Robert"} />
<Hello name={"Eddie"} />
<Hello />
<Hello name={"我是JSX屬性!!!"}>
<h2>hi, i'm Children</h2>
</Hello>
</>
);
// src/components/Hello.js
const Hello = (props) => {
console.log(props);
const { name = "world", children } = props
return (
<div className="border">
<h1>Hello, {name}</h1>
{children}
</div>
)
}
export { Hello }
/* src/styles/index.css */
.border {
width: 50%;
border: 2px solid rgb(68, 140, 140);
margin: 10px;
padding: 10px;
}
在這邊我特別 log 出來看看 Props 是什麼
我們發現 Props 其實就是一個物件
因為 Props 是一個物件所以我們就可以將 props 解構,並且拿到 name 這個 key 的 value,以及 Children 的 value
有發現嗎 Children 就是 我的 Hello 元件中所存在的子元素,要有多少個子元素都行
所以其實 Children 這個名字非常直觀
這邊我也賦予 name 一個預設值 "world",以防元件沒有傳入 Props 不會產生錯誤
這時我將畫面給大家看
是不是更加了解了 什麼是 Props 了 !!
那我們就回到一開始的範例吧
再次客製化我們的元件吧~
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Item } from './components/Item';
const root = ReactDOM.createRoot(document.getElementById('root'));
const todoList = [
{ todo: "今天學習 React" , date: "2022/9/21"},
{ todo: "今天學習 Ruby" , date: "2022/9/22"},
{ todo: "今天學習 JavaScript" , date: "2022/9/23"},
{ todo: "今天學習 GO" , date: "2022/9/24"},
]
root.render(
<>
{todoList.map(({todo, date})=> {
return <Item todo={todo} date={date} />
})}
</>
);
// src/components/Items
const Item = ({todo, date}) => {
// 我們也可以在傳入 props 的時候將他直接解構
// const { todo ,date } = props
return (
<div>
<div className="item">
<p className="todo">記事:{todo}</p>
<p className="date">紀錄時間:{date}</p>
</div>
</div>
)
}
export { Item }
再加上一點 CSS
.date {
color: red;
}
.todo {
color: blue;
}
這樣就可以有效並且重複利用 Component
依照不同的 Props 呈現不同的內容了
今天舉了許多例子去介紹 Props,也希望大家包括我自己能夠更加了解 React,若有問題,或是文章有需要改進的地方也歡迎大家在下面留言
感謝大家